/*
 * @Author: wuqingchun
 * @Date: 2023-08-18 17:00:41
 * @Description: 
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-01-11 14:50:23
 */
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ifaddrs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "ftpc.h"
#include "ftpc_util.h"

#define FTPC_CMD_DELIM " \t"

int FTPC_util_GetLocalAddr(const struct in_addr* pstAddr, struct in_addr* pstOutAddr)
{
    int iErr;
    struct ifaddrs *pstIFAddrs, *pstTemp;
    struct in_addr* pstLAddr;
    struct in_addr* pstLMask;

    iErr = getifaddrs(&pstIFAddrs);
    if (iErr == -1) 
    {
        perror("getifaddrs");
        return iErr;
    }

    iErr = -1;
    for (pstTemp = pstIFAddrs; pstTemp != NULL; pstTemp = pstTemp->ifa_next)
    {
        //printf("%p\n", pstTemp);
        if (pstTemp->ifa_addr == NULL || 
            pstTemp->ifa_netmask == NULL ||
            pstTemp->ifa_addr->sa_family != AF_INET)
        {
            continue;
        }

        // 检查是否为同网段地址
        pstLAddr = &((struct sockaddr_in *)pstTemp->ifa_addr)->sin_addr;
        pstLMask = &((struct sockaddr_in *)pstTemp->ifa_netmask)->sin_addr;
        if ((pstAddr->s_addr & pstLMask->s_addr) == (pstLAddr->s_addr & pstLMask->s_addr))
        {
            *pstOutAddr = *pstLAddr;
            iErr = 0;
            break;
        }
    }
    
    freeifaddrs(pstIFAddrs);

    return iErr;
}


// 设置描述符为非阻塞模式
int FTPC_util_SetNoBlock(int iFd)
{
    int iFlags;

    iFlags = fcntl(iFd, F_GETFL);
    if (iFlags == -1)
    {
        return -1;
    }

    iFlags |= O_NONBLOCK;
    return fcntl(iFd, F_SETFL, iFlags);
}

int FTPC_util_ParseLine(FTPC_CMD_INFO_S* pstCmdInfo, char* pcLine)
{
    char* pcSavePtr;
    char *pcToken;
    int iErr = 0;

    pstCmdInfo->uiCount = 0;

    iErr = -1;
    
    while ((pcToken = strtok_r(pcLine, FTPC_CMD_DELIM, &pcSavePtr)) != NULL)
    {
        pcLine = NULL;
        
        if (pstCmdInfo->uiCount >= FTPC_CMD_ARG_COUNT_MAX)
        {
            // 多出的参数不解析
            break;
        }

        pstCmdInfo->apcItems[pstCmdInfo->uiCount] = pcToken;
        pstCmdInfo->uiCount++;
    }

    if (pstCmdInfo->uiCount > 0)
    {
        iErr = 0;
    }

    return iErr;
}

int FTPC_util_ReadLine(FTPC_CMD_INFO_S* pstCmdInfo, char **ppcLine)
{
    size_t ulLen = 0;
    char* pcTemp;
    int iErr = 0;

    pstCmdInfo->uiCount = 0;

    iErr = getline(ppcLine, &ulLen, stdin);
    if (iErr == -1)
    {
        return iErr;
    }

    pcTemp = *ppcLine;
    if (iErr > 0)
    {
        pcTemp[iErr - 1] = '\0';// 去除换行符
    }

    return FTPC_util_ParseLine(pstCmdInfo, pcTemp);
}

int FTPC_util_GetUserInput(const char* pcPrompt, FTPC_CMD_INFO_S* pstCmdInfo)
{
    printf("%s", pcPrompt);
    char* pcLine = g_stFTPCClient.szCmdLine;
    return FTPC_util_ReadLine(pstCmdInfo, &pcLine);
}

// 开启直接 IO 模式
int FTPC_util_EnableDirectIO(int iFd)
{
    int iFlags;

    iFlags = fcntl(iFd, F_GETFL);
    if (iFlags == -1)
    {
        return -1;
    }

    iFlags |= __O_DIRECT;
    return fcntl(iFd, F_SETFL, iFlags);
}